package com.tmt.im.manager.interfaces.impl;

import com.alibaba.fastjson2.JSONObject;
import com.tmt.im.common.pojo.IMUserPoJo;
import com.tmt.im.common.yunxin.YunXinHelper;
import com.tmt.im.jpa.entity.IMUser;
import com.tmt.im.jpa.repository.IMFriendApplyRepo;
import com.tmt.im.manager.common.Constant;
import com.tmt.im.manager.config.beans.YunXinProperties;
import com.tmt.im.manager.interfaces.IYunXinInterface;
import com.tmt.im.manager.interfaces.beans.ConversationType;
import com.tmt.im.manager.interfaces.beans.CustomMsg;
import com.tmt.im.manager.interfaces.beans.MessageType;
import lombok.extern.slf4j.Slf4j;
import org.apache.ignite.Ignite;
import org.apache.ignite.IgniteCache;
import org.springframework.beans.BeansException;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.core.annotation.Order;
import org.springframework.http.HttpMethod;
import org.springframework.util.CollectionUtils;
import org.springframework.util.LinkedMultiValueMap;
import org.springframework.util.MultiValueMap;
import org.springframework.util.StringUtils;

import java.lang.reflect.Method;
import java.text.MessageFormat;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;

/**
 * @Description TODO
 * @Author wuyi
 * @Date 2024/8/23 20:28
 * @Version 1.0
 **/
@Slf4j
@Order(1)
public class YunXinManager_V10 implements IYunXinInterface, ApplicationContextAware {

    private static final String SUPPORTED_API_VERSION = "v10";
    private static final String REG_ACCOUNT_URL = "https://open.yunxinapi.com/im/v2/accounts";

    private static final String APPLY_FRIEND_URL = "https://open.yunxinapi.com/im/v2/friends";

    private static final String SEND_CUSTOMIZED_NOTIFY = "https://open.yunxinapi.com/im/v2/custom_notification";

    private static final String SEND_MESSAGE = "https://open.yunxinapi.com/im/v2/conversations/{conversation_id}/messages";

    private static final String DELETE_FRIEND = "https://open.yunxinapi.com/im/v2/friends/{account_id}";

    private YunXinProperties yunXinProperties;

    private Ignite ignite;

    private IMFriendApplyRepo imFriendApplyRepo;

    @Override
    public boolean supported(IYunXinInterface iYunXinInterface, Method method, Object[] params) {
        return SUPPORTED_API_VERSION.equalsIgnoreCase(Constant.YUN_XIN_API_VERSION);
    }

    @Override
    public boolean registerUser(IMUser imUser, StringBuilder error) {
        try {
            MultiValueMap<String, Object> configuration = new LinkedMultiValueMap<>();
            MultiValueMap<String, Object> user_information = new LinkedMultiValueMap<>();
            MultiValueMap<String, Object> reqParam = new LinkedMultiValueMap<>();
            reqParam.add("account_id", "" + imUser.getId());
            reqParam.add("token", "");
            reqParam.add("configuration", configuration);
            reqParam.add("user_information", user_information);

            configuration.add("enabled", true);
            configuration.add("p2p_chat_banned", false);
            configuration.add("team_chat_banned", false);
            configuration.add("chatroom_chat_banned", false);
            configuration.add("qchat_chat_banned", false);

            user_information.add("name", imUser.getUsername());
            user_information.add("avatar", imUser.getAvatar());
            user_information.add("sign", "");
            user_information.add("email", "");
            user_information.add("birthday", "");
            user_information.add("mobile", imUser.getMobile());
            user_information.add("gender", 0);//用户性别，0-未知，1-男，2-女

            JSONObject extension = new JSONObject();
            extension.put("grade", imUser.getGrade() != null ? imUser.getGrade() : 0);
            extension.put("memberCode", imUser.getMemberCode());
            user_information.add("extension", extension.toJSONString());

            JSONObject jsonObject = YunXinHelper.exchange(REG_ACCOUNT_URL, HttpMethod.POST, reqParam, yunXinProperties);
            switch (jsonObject.getInteger("code")) {
                case 200, 102405 -> {
                    if (jsonObject.containsKey("token")) {
                        imUser.setImToken(jsonObject.getString("token"));
                    }
                    return true;
                }
                case 403 -> throw new Exception("云信接口——鉴权失败");
                case 414 -> throw new Exception("云信接口——参数错误: " + jsonObject.get("msg"));
                case 500 -> throw new Exception("云信接口——服务器内部错误");
                //case 102405 -> throw new Exception("云信接口——用户已存在");
                case 102434 -> throw new Exception("云信接口——超过最大账号数");
                case 102449 -> throw new Exception("云信接口——账号请求需要重试");
                case 103451 -> throw new Exception("云信接口——用户资料反垃圾");
                default -> throw new Exception("云信业务错误");
            }
        } catch (Exception ex) {
            error.append(ex.getMessage());
        }
        return false;
    }

    @Override
    public boolean updateUserInfo(IMUser imUser, StringBuilder error) {
        error.append("未实现");
        return false;
    }

    @Override
    public boolean updateUserAvatar(Long userId, String avatar, StringBuilder error) {
        return false;
    }

    @Override
    public boolean updateSessionAvatar(Long tid, Long ownerId, String avatar, StringBuilder error) {
        return false;
    }

    @Override
    public boolean refreshUserToken(IMUser imUser, StringBuilder error) {
        error.append("未实现");
        return false;
    }

    @Override
    public boolean applyFriend(Long creatorId, Long targetId, int type,
                               String targetAlias, String note, StringBuilder error) {
        try {
            MultiValueMap<String, Object> reqParam = new LinkedMultiValueMap<>();
            reqParam.add("account_id", "" + creatorId);
            reqParam.add("friend_account_id", "" + targetId);
            if (StringUtils.hasText(targetAlias)) {
                reqParam.add("alias", targetAlias);
            }
            if (StringUtils.hasText(note)) {
                reqParam.add("message", note);
            }

            JSONObject jsonObject = YunXinHelper.exchange(APPLY_FRIEND_URL, HttpMethod.POST, reqParam, yunXinProperties);
            switch (jsonObject.getInteger("code")) {
                case 200, 104405 -> {
                    return true;
                }
                case 414 -> throw new Exception("云信接口——参数错误: " + jsonObject.get("msg"));
                case 102404 -> throw new Exception("云信接口——用户不存在");
                case 104429 -> throw new Exception("云信接口——不允许对自己进行好友操作");
                case 104435 -> throw new Exception("云信接口——好友数量超出上限");
                case 104301 -> throw new Exception("云信接口——对方好友数量超出上限");
                case 104449 -> throw new Exception("云信接口——好友操作频率超限");
                case 104451 -> throw new Exception("云信接口——好友申请信息未通过反垃圾审核");
                case 500 -> throw new Exception("云信接口——服务器内部错误");
                default -> throw new Exception("云信业务错误");
            }
        } catch (Exception ex) {
            error.append(ex.getMessage());
        }
        return false;
    }

    @Override
    public boolean updateFriend(Long creatorId, Long targetId, String targetAlias, StringBuilder error) {
        return false;
    }

    public boolean sendFriendApplyNotify(Long fromId, Long toId, JSONObject content, StringBuilder error) {
        try {
            JSONObject push_config = new JSONObject();
            push_config.put("push_content", "发来了一条好友申请");
            push_config.put("push_enabled", true);
            push_config.put("push_nick_enabled", true);

            MultiValueMap<String, Object> reqParam = new LinkedMultiValueMap<>();
            reqParam.add("sender_id", "" + fromId);
            reqParam.add("receiver_id", "" + toId);
            reqParam.add("type", "1");
            reqParam.add("content", content.toJSONString());
            reqParam.add("push_config", push_config);

            JSONObject jsonObject = YunXinHelper.exchange(SEND_CUSTOMIZED_NOTIFY, HttpMethod.POST, reqParam, yunXinProperties);
            switch (jsonObject.getInteger("code")) {
                case 200 -> {
                    return true;
                }
                case 414 -> throw new Exception("云信接口——参数错误: " + jsonObject.get("msg"));
                case 416 -> throw new Exception("云信接口——频率超限");
                case 102404 -> throw new Exception("云信接口——用户不存在");
                case 108404 -> throw new Exception("云信接口——群不存在");
                case 108302 -> throw new Exception("云信接口——非高级群");
                case 108311 -> throw new Exception("云信接口——超大群服务未开通");
                case 109404 -> throw new Exception("云信接口——群成员不存在");
                case 500 -> throw new Exception("云信接口——服务器内部错误");
                case 503 -> throw new Exception("云信接口——服务器繁忙");
                default -> throw new Exception("云信业务错误");
            }
        } catch (Exception ex) {
            error.append(ex.getMessage());
        }
        return false;
    }

    public boolean sendMessage(Long fromId, Long toId, ConversationType type, int subType,
                               MessageType contentType, String textMsg,
                               JSONObject attachment, Map<String, JSONObject> options, StringBuilder error) {
        String conversation_id = MessageFormat.format("{0}|{1}|{2}", "" + fromId, "" + type.getType(), "" + toId);
        String url = SEND_MESSAGE.replace("{conversation_id}", conversation_id);
        try {
            JSONObject message = null;
            if (!options.containsKey("message")) {
                message = new JSONObject();
                message.put("message_type", contentType.getType());
                message.put("sub_type", subType);
                message.put("text", textMsg);
                if (attachment != null) {
                    message.put("attachment", attachment);
                }
            } else {
                message = options.get("message");
            }

            MultiValueMap<String, Object> reqParam = new LinkedMultiValueMap<>();
            reqParam.add("sender_no_sense", false);
            reqParam.add("receiver_no_sense", false);
            reqParam.add("message", message);

            List<String> keys = List.of("message_config", "p2p_option", "push_config");
            if (!CollectionUtils.isEmpty(options)) {
                for (String key : keys) {
                    if (options.containsKey(key)) {
                        reqParam.add(key, options.get(key));
                    } else {
                        JSONObject option = new JSONObject();
                        if ("message_config".equals(key)) {
                            option.put("unread_enabled", false);
                            option.put("mutil_sync_enabled", true);
                            option.put("offline_enabled", true);
                            option.put("history_enabled", false);
                            option.put("roaming_enabled", true);
                            option.put("conversation_update_enabled", false);
                        } else if ("p2p_option".equals(key)) {
                            option.put("check_friend", true);
                        } else if ("push_config".equals(key)) {
                            option.put("push_enabled", false);
                            option.put("push_nick_enabled", false);
                            option.put("push_forcepush_all", false);
                        }
                        reqParam.add(key, option);
                    }
                }
            }

            JSONObject jsonObject = YunXinHelper.exchange(url, HttpMethod.POST, reqParam, yunXinProperties);
            switch (jsonObject.getInteger("code")) {
                case 200 -> {
                    return true;
                }
                case 414 -> throw new Exception("云信接口——参数错误: " + jsonObject.get("msg"));
                case 102404 -> throw new Exception("云信接口——用户不存在");
                case 102421 -> throw new Exception("云信接口——用户被禁言");
                case 102422 -> throw new Exception("云信接口——用户被禁用");
                case 104404 -> throw new Exception("云信接口——好友不存在");
                case 107410 -> throw new Exception("云信接口——该App未开启发消息功能");
                case 107451 -> throw new Exception("云信接口——该消息未通过反垃圾审核");
                case 107302 -> throw new Exception("云信接口——由于群成员过多导致标记已读失败，消息发送失败");
                case 107329 -> throw new Exception("云信接口——不是机器人帐号");
                case 107330 -> throw new Exception("云信接口——不允许发送方和接收方均无感知");
                case 108311 -> throw new Exception("云信接口——超大群服务未开通");
                case 108404 -> throw new Exception("云信接口——群不存在");
                case 108302 -> throw new Exception("云信接口——非高级群");
                case 108423 -> throw new Exception("云信接口——群全体禁言");
                case 108306 -> throw new Exception("云信接口——群普通成员禁言");
                case 109404 -> throw new Exception("云信接口——群成员不存在");
                case 109424 -> throw new Exception("云信接口——群成员被禁言");
                case 107338 -> throw new Exception("云信接口——群定向消息不允许单向删除");
                case 107339 -> throw new Exception("云信接口——定向列表不能包含消息发送者");
                case 108318 -> throw new Exception("云信接口——群定向消息功能未开启");
                case 108321 -> throw new Exception("云信接口——群消息定向成员可见时不支持新成员可见");
                case 109318 -> throw new Exception("云信接口——强推列表包含非定向成员");
                case 107340 -> throw new Exception("云信接口——机器人消息不能是定向消息");
                case 108319 -> throw new Exception("云信接口——超大群消息不支持定向列表不可见");
                case 108320 -> throw new Exception("云信接口——超大群定向消息不支持新成员可见");
                case 500 -> throw new Exception("云信接口——服务器内部错误");
                default -> throw new Exception("云信业务错误");
            }
        } catch (Exception ex) {
            error.append(ex.getMessage());
        }
        return false;
    }

    @Override
    public boolean deleteFriend(Long currentUserId, Long friendUserId, StringBuilder error) {
        String url = DELETE_FRIEND.replace("{account_id}", "" + currentUserId);
        try {
            MultiValueMap<String, Object> reqParam = new LinkedMultiValueMap<>();
            reqParam.add("friend_account_id", "" + friendUserId);
            reqParam.add("delete_alias", true);

            JSONObject jsonObject = YunXinHelper.exchange(url, HttpMethod.DELETE, reqParam, yunXinProperties);
            switch (jsonObject.getInteger("code")) {
                case 200 -> {
                    return true;
                }
                case 414 -> throw new Exception("云信接口——参数错误: " + jsonObject.get("msg"));
                case 102404 -> throw new Exception("云信接口——用户不存在");
                case 104404 -> throw new Exception("云信接口——好友不存在");
                case 104449 -> throw new Exception("云信接口——好友操作频率超限");
                case 500 -> throw new Exception("云信接口——服务器内部错误");
                default -> throw new Exception("云信业务错误");
            }
        } catch (Exception ex) {
            error.append(ex.getMessage());
        }
        return false;
    }

    @Override
    public boolean pullInBlackBill(Long currentUserId, Long friendId, boolean pullIn, StringBuilder error) {
        return false;
    }

    @Override
    public boolean enableNoDisturbing(Long currentUserId, Long friendId, boolean noDisturbing, StringBuilder error) {
        return false;
    }

    @Override
    public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
        ignite = applicationContext.getBean(Ignite.class);
        imFriendApplyRepo = applicationContext.getBean(IMFriendApplyRepo.class);
        yunXinProperties = applicationContext.getBean(YunXinProperties.class);
    }
}
